#pragma once

#include "BasicType.h"
#include "TagList.h"

namespace LightPlayer{

	struct GRADRECORD{
		uint8				m_Ratio;
		RGBA				m_Color;

		GRADRECORD();
		void init();
		void readFromStream(Stream* stream, int tag_shape = eDefineShape);
	};

	enum eSpreadMode{
		ePadMode = 0, eReflectMode = 1, eRepeatMode = 2, eReserved = 3 
	};

	enum eInterpolationMode{
		eNormalRGBInterpolation = 0, eLinearRGBInterpolation = 1, eReservedInterpolation = 2
	};

#define GRADIENT_MAX_CONTROL	(8)
#define GRADIENT_COLOR_CONTROLE_SIZE (GRADIENT_MAX_CONTROL*4)
	struct GRADIENT{
		bool				m_isLinear;
		uint8				m_SpreadMode;
		uint8				m_InterpolationMode;
		array<GRADRECORD>	m_GradientsRecords;
		float				m_ColorControl[GRADIENT_COLOR_CONTROLE_SIZE]; // max 8 color RGBA
		float				m_RatioControl[GRADIENT_MAX_CONTROL]; // max 8 ratio control

		GRADIENT();
		void init();
		void readFromStream(Stream* stream, int tag_shape = eDefineShape);
		void computeControlBuffer();
		const float*	getColorControl() const {return m_ColorControl;} 
		const float*	getRatioControl() const {return m_RatioControl;}
	};
	struct FOCALGRADIENT{
		GRADIENT			m_Gradient;
		float				m_FocalPoint;

		FOCALGRADIENT();
		void init();
		void readFromStream(Stream* stream, int tag_shape = eDefineShape);
	};

	enum eFillStyleType{
		eSolidFill = 0x00,
		eLinearGradientFill = 0x10,
		eRadialGradientFill = 0x12,
		eFocalRadialGradientFill = 0x13,
		eRepeatingBitmapFill = 0x40,
		eClippedBitmapFill = 0x41,
		eNonSmoothedRepeatingBitmapFill = 0x42,
		eNonSmoothedClippedBitmapFill = 0x43,
	};

	class Bitmap;

	struct FILLSTYLE{
		uint8				m_FillStyleType;
		RGBA				m_Color;
		MATRIX				m_GradientMatrix;
		GRADIENT			m_Gradient;
		FOCALGRADIENT		m_FocalGradient;
		uint16				m_BitmapId;
		MATRIX				m_BitmapMatrix;
		Bitmap*				m_pBitmap;
		
							FILLSTYLE();
							FILLSTYLE( RGBA _Color );
		void				init();
		void				readFromStream(Stream* stream, int tag_shape = eDefineShape );
		// bitmap
		bool				isBitmapFill() const												{return m_BitmapId != 0;}
		uint16				getBitmapId() const													{return m_BitmapId;}
		const MATRIX&		getBitmapMatrix() const												{return m_BitmapMatrix;}
		Bitmap*				getBitmap() const													{return m_pBitmap;}
		void				setBitmap(Bitmap* bitmap)											{m_pBitmap=bitmap;}
		// gradient
		bool				isGradientFill() const												{return (m_FillStyleType == eLinearGradientFill) || (m_FillStyleType == eRadialGradientFill);}
		const MATRIX&		getGradientMatrix()	const											{return m_GradientMatrix;}
		const GRADIENT&		getGradient() const													{return m_Gradient;}
	};

	class FILLSTYLEARRAY{
	public:
		array<FILLSTYLE>	m_FillStyles;


		FILLSTYLEARRAY();
		void init();
		void readFromStream(Stream* stream, int tag_shape = eDefineShape);
		void addFromStream(Stream* stream, int tag_shape = eDefineShape);
		
		int	size()const{return m_FillStyles.size();}
		FILLSTYLE& at(uint32 pos);
		static FILLSTYLE s_empty_fill_style;
		static FILLSTYLE s_white_fill_style;
	};





	enum eLineCapStyle{
		eRoundCap = 0,
		eNoCap = 1,
		eSquareCap = 2
	};

	enum eLineJoinStyle{
		eRoundJoin = 0,
		eBevelJoin = 1,
		eMiterJoin = 2
	};

	struct LINESTYLE{
		float				m_Width;
		RGBA				m_Color;

		LINESTYLE();
		void init();
		void readFromStream(Stream* stream, int tag_shape = eDefineShape);
	};

	struct LINESTYLE2{
		float				m_Width;
		RGBA				m_Color;
		uint8				m_StartCapStyle;
		uint8				m_EndCapStyle;
		uint8				m_JoinStyle;
		bool				m_NoHScaleFlag;
		bool				m_NoVScaleFlag;
		bool				m_PixelHintingFlag;
		bool				m_Close;
		float				m_MiterLimitFactor;
		FILLSTYLE			m_FillStyle;

		LINESTYLE2();
		void init();
		void readStyle1FromStream( Stream* stream, int tag_shape = eDefineShape );
		void readFromStream(Stream* stream, int tag_shape = eDefineShape);
	};

	struct LINESTYLEARRAY{
		array<LINESTYLE2>	m_LineStyles2;

		LINESTYLEARRAY();
		void init();
		void readFromStream(Stream* stream, int tag_shape = eDefineShape);
		void addFromStream(Stream* stream, int tag_shape = eDefineShape);

		LINESTYLE2& at(uint32 pos);
		static LINESTYLE2 s_empty_line_style;
	};
};